# ----------------------------------------------------------------------------
#       Copyright (C) 2013-2014 Huynh Vi Lam  <domovilam@gmail.com>
#
#       This file is part of pimucha.
#
#	This program is free software: you can redistribute it and/or modify
#	it under the terms of the GNU General Public License as published by
#	the Free Software Foundation, either version 3 of the License, or
#	(at your option) any later version.
#	
#	This program is distributed in the hope that it will be useful,
#	but WITHOUT ANY WARRANTY; without even the implied warranty of
#	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#	GNU General Public License for more details.
#	
#	You should have received a copy of the GNU General Public License
#	along with this program.  If not, see <http://www.gnu.org/licenses/>.
# ----------------------------------------------------------------------------

import logging
from piHAlibs import (my_fctname,coroutine,db2dict,tstampdev,sensorid)
from .orelibs import *
from .parsers import OREDECODERS

logger = logging.getLogger()


@my_fctname
@coroutine
def oredecoder(targets,rejected=None,newids=None,rawevt=None):
    """
    Decoders for Oregon sensor events from RFXCOM and TSDUO
    """
    condition = " WHERE typeunit = 'sensor'"
    ids = db2dict('UNITIDS',condition)
    rows = OREDECODERS
    while True:
        msgs = (yield)
       	logger.debug("Msgs received %s",repr(msgs))
        namedev, protocol, data, p, model, hdp, revt = msgs
        if protocol != 'oregon' : continue
       	logger.debug("Protocol %s Header %s Model %s",protocol, hdp, model)
        if (hdp,model) in rows:
            row = rows[(hdp,model)]
        else:
            if rejected: rejected.send(['NEW_DECODER',protocol] + msgs)
            continue
        # row = [chksmodel,chkseval,addbyte,listdata,dataeval]
       	logger.debug("Oredecoder Row %s",repr(row))
        #Check Model
        if row[0] != '':
            try:
                if not eval(row[0]):
                     if rejected: rejected.send(['FAIL_CHKSID',repr(row[0])] + msgs)
       	       	     continue
       	    except Exception as e:
       	        logger.debug("Exception / Error %s",repr(e))
                if rejected: rejected.send(['ERR_CHKSID',repr(row[0])] + msgs)
       	       	continue
       	#Check data with fonction in row[1]
       	if row[1] != '':
       	    try:
       	       	if not eval(row[1]):
       	       	     if rejected: rejected.send(['FAIL_CHKSUM',repr(row[1])] + msgs)
       	       	     continue
       	    except Exception as e:
       	        logger.debug("Exception / Error %s",repr(e))
       	       	if rejected: rejected.send(['ERR_CHKSUM',repr(row[7])] + msgs)
       	       	continue
       	#Sensor address : addr byte in row[2]
        addr =  '0x%02x' % (p[row[2]] & 0xFF)
        logger.debug("Address of Sensor  %s",addr)
       	#Sensor data with list of data in row[3] and fonction in row[4]
       	ld = row[3].split()
       	try:
       	    res = eval(row[4])
       	except Exception as e:
       	    logger.debug("Exception / Error %s",repr(e))
       	    if rejected: rejected.send(['ERR_DECODE',repr(row[4])] + msgs)
       	    continue
       	#Sensor Unit / Id
        unit = model + '_' + addr
        V = (protocol,unit)
       	if V not in ids:
            logger.debug("New sensor detected %s", repr(V))
            if newids:
                type,subtype = model2type(model)
                ids = sensorid([protocol,model,'sensor', unit,type,subtype,row[3]])
       	    continue
       	hd = tstampdev(namedev)
       	for d in ld:
       	    event = hd + ['sensor'] + [d, unit, res[ld.index(d)]]
            logger.debug("Function oredecoder for %s",repr(event))
            for target in targets:
                target.send(event)

